package com.ruoyi.web.controller.system;

import com.ruoyi.business.Util.RSAUtils;
import com.ruoyi.business.common.CommonValues;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.system.common.RedisKeyPrefix;
import com.ruoyi.system.service.ISysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 登录验证
 * 
 */
@RestController
public class SysLoginController
{
    @Autowired
    private SysLoginService loginService;

    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 登录方法
     * 
     * @param loginBody 登录信息
     * @return 结果
     */
    @PostMapping("/login")
    public AjaxResult login(@RequestBody LoginBody loginBody)
    {
        //判断账号是否登录,已登录直接拒绝登录
//        String username = loginBody.getUsername();
//        Object o = redisTemplate.opsForValue().get(RedisKeyPrefix.ROLE_PREFIX
//                + username);
//        if (o!=null){
//            return AjaxResult.error("账号已在其它地方登录");
//        }
        AjaxResult ajax = AjaxResult.success();
        String token;
        if (loginBody.getType() == null){
            return AjaxResult.error("请选择登录类型");
        }
        boolean flag;
        //先判断是否以openId形式登录
        if (StringUtils.isNotEmpty(loginBody.getOpenId()) && StringUtils.isEmpty(loginBody.getUsername()+loginBody.getPassword())){
            //openId登录
            LoginBody login = loginService.getLoginBodyByOpenId(loginBody.getOpenId());
            if (login == null){
                return AjaxResult.error("用户未进行过登录");
            }
            //将用户登录时选择的身份存入redis,将过期时间设为10s防止未知异常发生
            redisTemplate.opsForValue().set(RedisKeyPrefix.ROLE_PREFIX
                    +login.getUsername(),loginBody.getType(),10,TimeUnit.SECONDS);
            token = loginService.loginByOpenId(loginBody);
            if (token == null){
                //用户未绑定openId
                return AjaxResult.error("用户未进行过登录");
            }
            flag = (boolean) redisTemplate.opsForValue().get(RedisKeyPrefix.ROLE_FLAG_PREFIX
                    + login.getUsername());
        }else{
            loginBody.setPassword(RSAUtils.decryptRSADefault(CommonValues.PRIVATEKEY,loginBody.getPassword()));
            //将用户登录时选择的身份存入redis
            redisTemplate.opsForValue().set(RedisKeyPrefix.ROLE_PREFIX
                    +loginBody.getUsername(),loginBody.getType(),30, TimeUnit.MINUTES);
            if (StringUtils.isNotEmpty(loginBody.getOpenId())){
                token = loginService.loginByOpenId(loginBody);
            }else{
                token = loginService.login(loginBody.getUsername(),
                        loginBody.getPassword(), loginBody.getCode(),
                        loginBody.getUuid());
            }

           flag = (boolean) redisTemplate.opsForValue().get(RedisKeyPrefix.ROLE_FLAG_PREFIX
                    + loginBody.getUsername());
        }
        redisTemplate.delete(RedisKeyPrefix.ROLE_FLAG_PREFIX
                + loginBody.getUsername());
        if (flag){
            ajax.put(Constants.TOKEN, token);
        }else{
            return AjaxResult.error("账号无该权限");
        }
        // 生成令牌


        return ajax;
    }

    /**
     * 获取用户信息
     * 
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo()
    {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }
    /**
     * 获取用户角色
     */
    @GetMapping("getRoles")
    public AjaxResult getRoleIds()
    {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Long userId = user.getUserId();
        Long roleId = (Long) redisTemplate.opsForValue().get(RedisKeyPrefix.ROLE_PREFIX
                +SecurityUtils.getUsername());
        Map<String,Object> map = new HashMap<>();
        map.put("roles",roleId);
        map.put("userId",userId);
        return AjaxResult.success(map);
    }

    /**
     * 获取路由信息
     * 
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters()
    {
        Long userId = SecurityUtils.getUserId();
        Long roleId = (Long) redisTemplate.opsForValue().get(RedisKeyPrefix.ROLE_PREFIX
                +SecurityUtils.getUsername());
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId,roleId);
//        List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
        return AjaxResult.success(menuService.buildMenus(menus));
    }
}
